#include "core.h"

#pragma warning( disable : 4231 )
#pragma warning( disable : 4129 )

#include "LogMgr.h"
#include <log4cxx/patternlayout.h>
#include <log4cxx/consoleappender.h>
#include <log4cxx/helpers/dateformat.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/helpers/system.h>

IMP_SINGLETON_CLASS(CLogMgr)

CLogMgr::Level* CLogMgr::Level::level_off_ = NULL;
CLogMgr::Level* CLogMgr::Level::level_fatal_ = NULL;
CLogMgr::Level* CLogMgr::Level::level_system_ = NULL;
CLogMgr::Level* CLogMgr::Level::level_error_ = NULL;
CLogMgr::Level* CLogMgr::Level::level_alarm_ = NULL;
CLogMgr::Level* CLogMgr::Level::level_warn_ = NULL;
CLogMgr::Level* CLogMgr::Level::level_info_ = NULL;
CLogMgr::Level* CLogMgr::Level::level_trace_ = NULL;
CLogMgr::Level* CLogMgr::Level::level_debug_ = NULL;
CLogMgr::Level* CLogMgr::Level::level_all_ = NULL;

void CLogMgr::Level::init()
{
	level_off_	= new Level(new log4cxx::Level(log4cxx::Level::OFF_INT, LOG4CXX_STR("OFF"), 3));
	level_fatal_	= new Level(new log4cxx::Level(log4cxx::Level::FATAL_INT, LOG4CXX_STR("FATAL"), 3));
	level_system_	= new Level(new log4cxx::Level(log4cxx::Level::FATAL_INT, LOG4CXX_STR("SYSTEM"), 3));
	level_error_	= new Level(new log4cxx::Level(log4cxx::Level::ERROR_INT, LOG4CXX_STR("ERROR"), 3));
	level_alarm_	= new Level(new log4cxx::Level(log4cxx::Level::ERROR_INT, LOG4CXX_STR("ALARM"), 3));
	level_warn_	= new Level(new log4cxx::Level(log4cxx::Level::WARN_INT, LOG4CXX_STR("WARN"), 3));
	level_info_	= new Level(new log4cxx::Level(log4cxx::Level::INFO_INT, LOG4CXX_STR("INFO"), 3));
	level_trace_	= new Level(new log4cxx::Level(log4cxx::Level::TRACE_INT, LOG4CXX_STR("TRACE"), 3));
	level_debug_	= new Level(new log4cxx::Level(log4cxx::Level::DEBUG_INT, LOG4CXX_STR("DEBUG"), 3));
	level_all_	= new Level(new log4cxx::Level(log4cxx::Level::ALL_INT, LOG4CXX_STR("ALL"), 3));
}

log4cxx::helpers::TimeZonePtr CLogMgr::LoggerLocalFileAppender::tz_(log4cxx::helpers::TimeZone::getDefault());


void CLogMgr::LoggerLocalFileAppender::setMyFile(const log4cxx::LogString& file)
{
	filename_ = log4cxx::helpers::StringHelper::trim(file);
	DailyRollingFileAppender::setFile(filename_);
}

void CLogMgr::LoggerLocalFileAppender::setTimeZone(const log4cxx::LogString& timezone)
{

}

CLogMgr::CLogMgr()
{
	memset(message_, 0, sizeof(message_));
	CLogMgr::Level::init();
}

CLogMgr::~CLogMgr()
{
	removeLocalFileLog(logger_name_);
}

void CLogMgr::init(const log4cxx::LogString& name)
{
	logger_ = log4cxx::Logger::getLogger(name);
	logger_->setLevel(new log4cxx::Level(log4cxx::Level::DEBUG_INT,LOG4CXX_STR("DEBUG"), 3));
}

const log4cxx::LogString CLogMgr::getName()
{
	return logger_->getName();
}

void CLogMgr::setName(const log4cxx::LogString& name)
{
}

bool CLogMgr::addConsoleLog()
{
	log4cxx::PatternLayoutPtr pattern_layout = new log4cxx::PatternLayout(LOG4CXX_STR("\%d{\%y\%m\%d-\%H:\%M:\%S }%c %5p: %m%n"));
	log4cxx::ConsoleAppenderPtr console_appender = new log4cxx::ConsoleAppender(pattern_layout);
	console_appender->setName(LOG4CXX_STR("console"));
	logger_->addAppender(console_appender);

	return true;
}

void CLogMgr::removeConsoleLog()
{
	log4cxx::AppenderPtr appender = logger_->getAppender(LOG4CXX_STR("console"));
	if (appender != NULL) {
		logger_->removeAppender(appender);
		appender->close();
	}
}
bool CLogMgr::addLocalFileLog(const log4cxx::LogString& file)
{
	log4cxx::PatternLayoutPtr pattern_layout = new log4cxx::PatternLayout(LOG4CXX_STR("\%d{\%y\%m\%d-\%H:\%M:\%S }%c %5p: %m%n"));
	log4cxx::helpers::Pool pool1;
	pattern_layout->activateOptions(pool1);
	LoggerLocalFileAppender* local_file_appender = new LoggerLocalFileAppender();
	local_file_appender->setDatePattern(LOG4CXX_STR("'.'yyyy-MM-dd-HH"));
	local_file_appender->setMyFile(file);
	local_file_appender->setLayout(pattern_layout);
	log4cxx::helpers::Pool pool2;
	local_file_appender->activateOptions(pool2);
	logger_name_ = (LOG4CXX_STR("localfile:") + file);
	local_file_appender->setName(LOG4CXX_STR("localfile:") + file);
	logger_->addAppender(local_file_appender);
	return true;
}

bool CLogMgr::addDailyLocalFileLog(const log4cxx::LogString& file)
{
	log4cxx::PatternLayoutPtr pattern_layout = new log4cxx::PatternLayout(LOG4CXX_STR("\%d{\%y\%m\%d-\%H:\%M:\%S }%c %5p: %m%n"));	
	log4cxx::helpers::Pool pool1;
	pattern_layout->activateOptions(pool1);
	LoggerLocalFileAppender* local_file_appender = new LoggerLocalFileAppender();
	local_file_appender->setDatePattern(LOG4CXX_STR("'.'yyyy-MM-dd"));
	local_file_appender->setMyFile(file);
	local_file_appender->setLayout(pattern_layout);
	log4cxx::helpers::Pool pool2;
	local_file_appender->activateOptions(pool2);
	logger_name_ = (LOG4CXX_STR("localfile:") + file);
	local_file_appender->setName(LOG4CXX_STR("localfile:") + file);
	logger_->addAppender(local_file_appender);
	return true;
}

void CLogMgr::removeLocalFileLog(const log4cxx::LogString& file)
{
	log4cxx::AppenderPtr ap = logger_->getAppender(LOG4CXX_STR("localfile:") + file);
	if (ap != NULL) {
		logger_->removeAppender(ap);
		ap->close();
	}
}

void CLogMgr::setLevel(const Level* level)
{
	logger_->setLevel(level->level_);
}

void CLogMgr::setLevel(const std::string& level)
{
	if ("off" == level)
		setLevel(Level::level_off_);
	else if ("fatal" == level)
		setLevel(Level::level_fatal_);
	else if ("alarm" == level)
		setLevel(Level::level_alarm_);
	else if ("error" == level)
		setLevel(Level::level_error_);	
	else if ("warn" == level)
		setLevel(Level::level_warn_);
	else if ("trace" == level)
		setLevel(Level::level_trace_);
	else if ("info" == level)
		setLevel(Level::level_info_);
	else if ("debug" == level)
		setLevel(Level::level_debug_);
	else if ("all" == level)
		setLevel(Level::level_all_);
}

void CLogMgr::log(const Level* level, const char* pattern, ...)
{
	boost::lock_guard< boost::mutex > lock( mutex_ );
	_getMessage(message_, MSGBUF_MAX, pattern);
	logger_->log(level->level_, message_);
}

void CLogMgr::forceLog(const Level* level, const char* pattern, ...)
{
	boost::lock_guard< boost::mutex > lock( mutex_ );
	_getMessage(message_, MSGBUF_MAX, pattern);
	logger_->forcedLog(level->level_, message_);
}

void CLogMgr::fatal(const char* pattern, ...)
{
	boost::lock_guard< boost::mutex > lock( mutex_ );
	_getMessage(message_, MSGBUF_MAX, pattern);
	logger_->fatal(message_);
}

void CLogMgr::error(const char* pattern, ...)
{
	boost::lock_guard< boost::mutex > lock( mutex_ );
	_getMessage(message_, MSGBUF_MAX, pattern);
	logger_->error(message_);
}

void CLogMgr::warn(const char* pattern, ...)
{
	boost::lock_guard< boost::mutex > lock( mutex_ );
	_getMessage(message_, MSGBUF_MAX, pattern);
	logger_->warn(message_);
}

void CLogMgr::info(const char* pattern, ...)
{
	boost::lock_guard< boost::mutex > lock( mutex_ );
	_getMessage(message_, MSGBUF_MAX, pattern);
	logger_->info(message_);
}

void CLogMgr::debug(const char* pattern, ...)
{
	boost::lock_guard< boost::mutex > lock( mutex_ );
	_getMessage(message_, MSGBUF_MAX, pattern);
	logger_->debug(message_);
}

void CLogMgr::alarm(const char* pattern, ...)
{
	boost::lock_guard< boost::mutex > lock( mutex_ );
	_getMessage(message_, MSGBUF_MAX, pattern);
	logger_->log(Level::level_alarm_->level_, message_);
}

void CLogMgr::trace(const char* pattern, ...)
{
	boost::lock_guard< boost::mutex > lock( mutex_ );
	_getMessage(message_, MSGBUF_MAX, pattern);
	logger_->log(Level::level_trace_->level_, message_);
}

void CLogMgr::system(const char* pattern, ...)
{
	boost::lock_guard< boost::mutex > lock( mutex_ );
	_getMessage(message_, MSGBUF_MAX, pattern);
	logger_->log(Level::level_system_->level_, message_);
}
